import {CanvasMode, HorizontalAlign, VerticalAlign, StretchDirection, EraserShapeMode, EraserMode} from './canvas/enums';
import { Stroke } from './canvas/stroke';
import { StrokePoint } from './geometry/point';
import { InnerCanvas } from './canvas/innercanvas';
import { Rect } from './geometry/rect';
import { EventEmitter } from 'events';
import { EventBase } from './eventbase';
import { InkProcessor } from './canvas/inkprocessor';
import { EventNames } from './canvas/eventnames';

export default class Canvas extends EventBase {
    /**画板设置参数 */
    private _innerCanvas: InnerCanvas;

    /**
     * 构造函数
     * @param canvas 
     */
    constructor(canvas: string | HTMLCanvasElement) {
        super();
        let _canvas: HTMLCanvasElement | null = null;
        if (typeof(canvas) === 'string') {
            const id = canvas as string;
            _canvas = document.getElementById(canvas) as HTMLCanvasElement;
        } else if (typeof(canvas) === 'object') {
            _canvas = <HTMLCanvasElement>canvas;
        }

        if (_canvas) {
            this._innerCanvas = new InnerCanvas(_canvas);
            // 订阅事件
            this._innerCanvas.addListener(EventNames.imageLoadedEventName, (source) => {
                this.publishEvent(EventNames.imageLoadedEventName, source);
            });
            this._innerCanvas.addListener(EventNames.htmlLoadedEventName, (source) => {
                this.publishEvent(EventNames.htmlLoadedEventName, source);
            });
            this._innerCanvas.addListener(EventNames.gesturedPointEventName, (source) => {
                this.publishEvent(EventNames.gesturedPointEventName, source);
            });
            this._innerCanvas.addListener(EventNames.newStrokeEventName, (source) => {
                this.publishEvent(EventNames.newStrokeEventName, source);
            });
            this._innerCanvas.addListener(EventNames.strokeDeletedEventName, (source) => {
                this.publishEvent(EventNames.strokeDeletedEventName, source);
            });
        } else {
            throw 'canvas 参数不正确';
        }
    }

    //#region 属性定义
    /**
     * 获取或设置画板模式
     */
    public get mode(): CanvasMode {
        return this._innerCanvas.mode;
    }
    public set mode(value: CanvasMode) {
        this._innerCanvas.mode = value;
    }
    /**获取或设置当前线条集合 */
    public get strokes(): Stroke[] {
        return this._innerCanvas.strokes;
    }
    public set strokes(value: Stroke[]) {
        this._innerCanvas.strokes = value;
    }
    /**获取或设置当前线条的粗细 */
    public get strokeWidth(): number {
        return this._innerCanvas.strokeWidth;
    }
    public set strokeWidth(value: number) {
        this._innerCanvas.strokeWidth = value;
    }
    /**获取或设置当前线条的颜色 */
    public get strokeColor(): string {
        return this._innerCanvas.strokeColor;
    }
    public set strokeColor(value: string) {
        this._innerCanvas.strokeColor = value;
    }
    /**获取或设置当前线条的颜色（设置此属性将导致重绘） */
    public get backgroundColor(): string {
        return this._innerCanvas.backgroundColor;
    }
    public set backgroundColor(value: string) {
        this._innerCanvas.backgroundColor = value;
    }
    /**
     * 获取或设置橡皮擦擦除模式
     */
    public get eraserMode() {
        return this._innerCanvas.eraserMode;
    }
    public set eraserMode(value: EraserMode) {
        this._innerCanvas.eraserMode = value;
    }
    /**
     * 获取或设置橡皮形状模式
     */
    public get eraserShapeMode() {
        return this._innerCanvas.eraserShapeMode;
    }
    public set eraserShapeMode(value: EraserShapeMode) {
        this._innerCanvas.eraserShapeMode = value;
    }
    /**
     * 获取或设置橡皮形状宽度
     */
    public get eraserWidth() {
        return this._innerCanvas.eraserWidth;
    }
    public set eraserWidth(value: number) {
        this._innerCanvas.eraserWidth = value;
    }
    /**获取或设置显示的底图图片url集合（设置此属性将导致重绘） */
    public get images() {
        return this._innerCanvas.imageUrls;
    }
    public set images(value: string[]) {
        this._innerCanvas.imageUrls = value;
    }
    /**获取或设置显示的html内容（设置此属性将导致重绘） */
    public get html() {
        return this._innerCanvas.html;
    }
    public set html(value: string) {
        this._innerCanvas.html = value;
    }
    /**获取或设置画板底图或显示的html内容的水平对齐方式，默认：左对齐 */
    public get horizontalAlign() {
        return this._innerCanvas.horizontalAlign;
    }
    public set horizontalAlign(value: HorizontalAlign) {
        this._innerCanvas.horizontalAlign = value;
    }
    /**获取或设置画板底图或显示的html内容的垂直对齐方式，默认：顶对齐 */
    public get verticalAlign() {
        return this._innerCanvas.verticalAlign;
    }
    public set verticalAlign(value: VerticalAlign) {
        this._innerCanvas.verticalAlign = value;
    }
    /**获取或设置是否自动处理图片拉伸 */
    public get autoStrech() {
        return this._innerCanvas.autoStrech;
    }
    public set autoStrech(value: boolean) {
        this._innerCanvas.autoStrech = value;
    }
    /**获取或设置图片自定义拉伸方向(autoStrech)为false时此设置有效
     * ,如果设置的图片为多张则设置为StretchDirection.Height不会起作用
     * ,如果设置的图片为多张verticalAlign设置也将不会起作用,只允许顶对齐
     */
    public get stretchDirection() {
        return this._innerCanvas.stretchDirection;
    }
    public set stretchDirection(value: StretchDirection) {
        this._innerCanvas.stretchDirection = value;
    }
    //#endregion

    //#region 公共方法
    public saveImage() {
        this._innerCanvas.saveImage();
    }
    /**
     * 清除所有线条
     */
    public clearStrokes() {
        this._innerCanvas.clearStrokes();
    }
    /**
     * 清除所有元素
     */
    public clearElements() {
        this._innerCanvas.clearElements();
    }
    /**
     * 重绘画板内容
     */
    public reDraw() {
        this._innerCanvas.reDraw();
    }
    /**
     * 强制刷新（图片、html内容等呈现区域）并重绘
     */
    public updateLayout() {
        this._innerCanvas.updateLayout();
    }
    /**
     * 获取所有线条的呈现区域
     */
    public getStrokesRect(): Rect {
        return this._innerCanvas.getStrokesRect();
    }
    /**
     * 获取底图图片呈现区域
     */
    public getImagesRect(): Rect {
        return this._innerCanvas.getImagesRect();
    }
    /**
     * 获取元素呈现区域
     */
    public getElementsRect() {
        return this._innerCanvas.getElementsRect();
    }
    /**
     * 绘制线段
     * @param p1 线段起点坐标
     * @param p2 线段终点坐标
     * @param lineWidth 线段粗细，如果为空则取当前画板的设置粗细
     * @param lineColor 线段颜色，如果为空则取当前画板的设置颜色
     */
    public drawLine(p1: StrokePoint, p2: StrokePoint, lineWidth?: number, lineColor?: string) {
        this._innerCanvas.drawLine(p1, p2, lineWidth, lineColor);
    }
    /**
     * 新建（添加）一个线条
     * @param lineId 线条id
     * @param lineWidth 线条粗细
     * @param lineColor 线条颜色
     * @param points 线条初始点集合
     */
    public addStroke(lineId: string, lineWidth: number, lineColor: string, points: StrokePoint[] = []): Stroke {
        return this._innerCanvas.addStroke(lineId, lineWidth, lineColor, points);
    }
    /**
     * 移除最后一根绘制的线条(撤销)
     */
    public strokeUndo() {
        return this._innerCanvas.strokeUndo();
    }
    /**
     * 恢复删除的线条(重做)
     */
    public strokeRedo() {
        return this._innerCanvas.strokeRedo();
    }
    /**
     * 旋转图片
     * @param imgIndex 
     * @param angle 
     */
    public imageRotate(imgIndex = 0, angle: number) {
        return this._innerCanvas.imageRotate(imgIndex, angle);
    }
    /**
     * 缩小图片
     * @param imgIndex 
     */
    public imageScaleIn(imgIndex = 0) {
        return this._innerCanvas.imageScaleIn(imgIndex);
    }
    /**
     * 放大图片
     * @param imgIndex 
     */
    public imageScaleOut(imgIndex = 0) {
        return this._innerCanvas.imageScaleOut(imgIndex);
    }
    /**
     * 提高图片亮度
     * @param imgIndex 
     */
    public brightLightUp(imgIndex = 0) {
        return this._innerCanvas.brightLightUp(imgIndex);
    }
    /**
     * 降低图片亮度
     * @param imgIndex 
     */
    public brightLightDown(imgIndex = 0) {
        return this._innerCanvas.brightLightDown(imgIndex);
    }
    /**
     * 判断加载成功的是否为单张图片
     */
    public isSingleImage() {
        return this._innerCanvas.isSingleImage();
    }
    /**
     * 判断加载成功的是否为多张图片
     */
    public isMutipleImage() {
        return this._innerCanvas.isMutipleImage();
    }
    /**
     * 判断是否存在加载成功的html
     */
    public existHtml() {
        return this._innerCanvas.existHtml();
    }
    //#endregion

}
